#![allow(dead_code)]

use super::{ControlEvent, OptResponse, RouterOps};
use crate::app::core::IpOps;
use crate::config::EntryPoint;
use anyhow::Result;
use std::future::Future;
use std::sync::Arc;
use wd_run::Context;

pub trait EntryPointBuilder: Send + Sync + 'static {
    fn build(&self, cfg: EntryPoint) -> Result<(Box<dyn EntryPointServer>, Box<dyn ControlPanel>)>;
}

#[async_trait::async_trait]
pub trait EntryPointServer: Send + Sync + 'static {
    async fn run(&mut self) -> Result<()>;
}

//每个EntryPoint都需要实现这个结构体
#[async_trait::async_trait]
pub trait ControlPanel: Send + Sync + 'static {
    async fn health(&mut self, _: Context) -> Result<()> {
        Ok(())
    }
    async fn ip_filter(&mut self, _: Context, _: Vec<IpOps>) -> Result<()>;
    async fn router(&mut self, _: Context, _: RouterOps) -> Result<Option<OptResponse>>;
    async fn stop(&mut self, _: Context) -> Result<Option<OptResponse>>;
    //是否需要重启 需要则返回配置 不需要则返回None
    fn config(&mut self, _: Context) -> Arc<EntryPoint>;
    //other ...
}

//每一个控制发生器都需要这样一个
#[async_trait::async_trait]
pub trait ControlEventDispenser: Send + Sync + 'static {
    async fn dispatch(&self, ce: ControlEvent) -> Result<Option<OptResponse>>;
}

//---------------------一些默认trait的实现-----------------------

// impl EntryPointServer for GoroutineResult<()> {
//     fn run(self) -> GoroutineResult<()> {
//         self
//     }
// }

#[async_trait::async_trait]
impl<F> EntryPointServer for F
where
    F: Future<Output = Result<()>> + Send + Sync + Unpin + 'static,
{
    async fn run(&mut self) -> Result<()> {
        self.await
    }
}

impl<F> EntryPointBuilder for F
where
    F: Fn(EntryPoint) -> Result<(Box<dyn EntryPointServer>, Box<dyn ControlPanel>)>
        + Send
        + Sync
        + 'static,
{
    fn build(&self, cfg: EntryPoint) -> Result<(Box<dyn EntryPointServer>, Box<dyn ControlPanel>)> {
        self(cfg)
    }
}
